package com.plian.system.service.ms.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.entity.ms.IssueSituation;
import com.plian.system.mapper.ms.IssueSituationMapper;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.service.ms.IIssueSituationService;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.sys.orgzation.OrgzationService;
import com.plian.system.service.wf.FormWorkflowService;
import com.plian.system.vo.ms.IssueSituationVO;
import com.plian.system.wrapper.ms.IssueSituationWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.plian.system.constant.sys.FormStatusConstant.UNREVIEWED;

/**
 * 月度计划表 服务实现类
 *
 * @author xiaohu
 */
@Slf4j
@Service
@AllArgsConstructor
public class IssueSituationServiceImpl extends BaseServiceImpl<IssueSituationMapper, IssueSituation> implements IIssueSituationService, BaseFlowService {

    private FormWorkflowService formWorkflowService;

    private IFormCodeService formCodeService;

    private IssueSituationMapper issueSituationMapper;

    private OrgzationService orgzationService;

    private IssueSituationWrapper issueSituationWrapper;


    private IOrgService orgService;

    private RectificationSituationServiceImpl rectificationSituationService;

    private static PageData lastyearSum(PageData pd, PageData pd2, String endTime) {
        //上年结转未整改问题
        Integer lastyearnum = pd2.getInteger("lastyearnum");
        //本月发现问题情况
        Integer thismonthnum = pd2.getInteger("thismonthnum");
        Integer thismonthadvicenum = pd2.getInteger("thismonthadvicenum");
        //本年累计发现问题
        Integer thisyearfindnum = pd2.getInteger("thisyearfindnum");
        Integer thisyearfindadvicenum = pd2.getInteger("thisyearfindadvicenum");
        //本年累计问题整改情况
        Integer thisyeartakenum = pd2.getInteger("thisyeartakenum");
        //本年未整改完成问题
        Integer thisyearnottakenum = pd2.getInteger("thisyearnottakenum");

        DecimalFormat df2 = new DecimalFormat("###.00");//这样为保持2位

        String fillDate = pd.getString("fillDate");
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        //String nowtime = df.format(new Date());// 当前时间
        String nowtime = endTime;// 结束时间
        String[] now = nowtime.split("-");
        String nowyear = now[0];//年
        String nowmonth = now[1];//月
        String lastyaer = String.valueOf(Integer.valueOf(nowyear) - 1);//上年
        String[] split = fillDate.split("-");
        String thisyear = split[0];//数据的年份
        String thismonth = split[1];//数据的月份

        String isRectification = pd.getString("rectificationSituation");
        //上年未整改问题
        if ((Integer.valueOf(thisyear) < Integer.valueOf(nowyear)) && !"124001".equals(isRectification)) {
            lastyearnum = 1 + lastyearnum;
            pd2.put("lastyearnum", lastyearnum);
        }

        //本月发现问题情况
        if (nowmonth.equals(thismonth) && thisyear.equals(nowyear)) {
            thismonthadvicenum =1 + thismonthadvicenum;
            thismonthnum = 1 + thismonthnum;
        }
        pd2.put("thismonthadvicenum", thismonthadvicenum);
        pd2.put("thismonthnum", thismonthnum);
        //本年发现问题
        if (thisyear.equals(nowyear) && (Integer.valueOf(thismonth) <= Integer.valueOf(nowmonth))) {
            thisyearfindadvicenum = 1 + thisyearfindadvicenum;
            thisyearfindnum = 1 + thisyearfindnum;
            if("124001".equals(isRectification)){//本年已整改完成的
                thisyeartakenum = 1 + thisyeartakenum;
            }else{//本年未整改完成
                thisyearnottakenum = 1 + thisyearnottakenum;
            }
        }



        pd2.put("thisyearfindadvicenum", thisyearfindadvicenum);
        pd2.put("thisyearfindnum", thisyearfindnum);

        pd2.put("thisyeartakenum", thisyeartakenum);


        pd2.put("thisyearnottakenum", thisyearnottakenum);

        String rate = null;
        Integer thisfindnum = thisyearfindnum + lastyearnum;
        if ((thisyeartakenum == 0) || (thisfindnum == 0)) {
            rate = "0";
        } else {
            Double aDouble = new Double(Math.round((thisyeartakenum * 10000) / thisfindnum));
            if (aDouble == 0d) {
                rate = "0";
            } else {
                rate = df2.format(aDouble / 100) + "%";
            }
        }
        pd2.put("rate", rate);
        pd2.put("remark", "");
        return pd2;
    }

    private static PageData initPd(PageData pd) {
        pd.put("rate", "0");
        pd.put("lastyearnum", 0);
        pd.put("thismonthnum", 0);
        pd.put("thismonthadvicenum", 0);
        pd.put("thisyearfindnum", 0);
        pd.put("thisyearfindadvicenum", 0);
        pd.put("thisyeartakenum", 0);
        pd.put("thisyearnottakenum", 0);
        return pd;
    }

    /**
     * 转换格林威治时间
     *
     * @param dateTime
     * @return
     */
    private static String covnDate(String dateTime) {
        DateFormat df2 = null;
        Date date1 = null;
        try {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
            Date date = df.parse(dateTime);
            SimpleDateFormat df1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK);
            date1 = df1.parse(date.toString());
            df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        } catch (ParseException e) {
            dateTime = dateTime.substring(0, 10);
            return dateTime;
        }
        return df2.format(date1);
    }

    private static PageData transforPD(PageData pd) {
        String reportType = pd.getString("reportType");
        switch (reportType) {
            case "122001":
                pd.put("reportType", "专项报告");
                break;
            case "122002":
                pd.put("reportType", "专项检查报告");
                break;
            case "122003":
                pd.put("reportType", "季度报告");
                break;
            case "122004":
                pd.put("reportType", pd.getString("otherReport"));
                break;
            case "122005":
                pd.put("reportType", "建议书");
                break;
            case "122006":
                pd.put("reportType", "年度监督检查报告");
                break;
            default:
                pd.put("reportType", "");
        }
        String issueType = pd.getString("issueType");
        switch (issueType) {
            case "123001":
                pd.put("issueType", "疑难处理");
                break;
            case "123002":
                pd.put("issueType", "即期整改");
                break;
            case "123003":
                pd.put("issueType", "限期整改");
                break;
            case "123004":
                pd.put("issueType", "联合督改");
                break;
            default:
                pd.put("issueType", "");
        }

        String signUpDate = pd.getString("signUpDate");
        if (signUpDate != null) {
            String s = signUpDate.split(" ")[0];
            pd.put("signUpDate", s);
        }

        String issueStartDate = pd.getString("issueStartDate");
        if (issueStartDate != null) {
            String s = issueStartDate.split(" ")[0];
            pd.put("issueStartDate", s);
        }

        String deadlineDate = pd.getString("deadlineDate");
        if (deadlineDate != null) {
            String s = deadlineDate.split(" ")[0];
            pd.put("deadlineDate", s);
        }

        String rectificationEndDate = pd.getString("rectificationEndDate");
        if (rectificationEndDate != null) {
            String s = rectificationEndDate.split(" ")[0];
            pd.put("rectificationEndDate", s);
        }

        return pd;
    }

    @Override
    public HashMap<String, Object> commit(String id) {
        handleStatus(Long.valueOf(id), FormStatusConstant.FLOW);
        //将需要提交的流程变量返回，用于工作流侧
        return new HashMap<String, Object>();
    }

    @Override
    public Boolean finish(String id) {
        return handleStatus(Long.valueOf(id), FormStatusConstant.FINISH);
    }

    @Override
    public Boolean reject(String id, int formState, String comment) {
        return handleStatus(Long.valueOf(id), formState);
    }

    @Override
    public Boolean checkIsExisted(Long id, String code) {
        if (Optional.ofNullable(code).isPresent()) {
            IssueSituation issueSituation = new IssueSituation();
            issueSituation.setCode(code);
            if (Optional.ofNullable(getOne(Condition.getQueryWrapper(issueSituation))).isPresent()) {
                return id != null && id.equals(getOne(Condition.getQueryWrapper(issueSituation)).getId());
            }
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean submit(IssueSituation issueSituation) {
        if (!Optional.ofNullable(issueSituation.getStatus()).isPresent()) {
            issueSituation.setStatus(FormStatusConstant.UNREVIEWED);
        }
        boolean result = saveOrUpdate(issueSituation);
        HashMap<String, Object> processVariable = new HashMap<>();
        formWorkflowService.startProcessAndSimulate(String.valueOf(issueSituation.getId()), issueSituation.getFormType(), processVariable);
        return result;
    }

    @Override
    public Boolean checkCancel(Long id) {
        IssueSituation issueSituation = getById(id);
        return Optional.ofNullable(issueSituation).isPresent();
    }

    @Override
    public boolean saveOrUpdate(IssueSituation issueSituation) {
        if (!Optional.ofNullable(issueSituation.getStatus()).isPresent()) {
            issueSituation.setStatus(UNREVIEWED);
        }
        if (!Optional.ofNullable(issueSituation.getId()).isPresent()) {
            //根据单据类型生成单据编码
            issueSituation.setCode(formCodeService.getCode(FormTypeConstant.MS_ISSUE_SITUATION));
            issueSituation.setFormType(String.valueOf(FormTypeConstant.MS_ISSUE_SITUATION));
        }
        return super.saveOrUpdate(issueSituation);
    }

    /**
     * 统一处理状态机事件方法
     *
     * @param id           主键
     * @param updateStatus 更新状态
     * @return boolean
     */
    private Boolean handleStatus(Long id, int updateStatus) {
        try {
            IssueSituation issueSituation = getById(id);
            /**
             * 设置审批人和审批时间
             */
            if (updateStatus == FormStatusConstant.FINISH) {
                issueSituation.setApprovedUser(TokenUtil.getTokenUserId());
                Date now = DateUtil.now();
                issueSituation.setApprovedTime(now);
            }
            issueSituation.setStatus(updateStatus);
            updateById(issueSituation);
            return true;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            return false;
        }
    }

    @Override
    public List<IssueSituation> issuelist(String id) {
        return issueSituationMapper.issuelist(id);
    }

    @Override
    public List<PageData> findByIds(List<String> formIds) {
        LambdaQueryWrapper<IssueSituation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(IssueSituation::getId, Func.toLongList(org.apache.commons.lang3.StringUtils.join(formIds, StringPool.COMMA)));
        List<IssueSituation> issueSituations = list(queryWrapper);
        List<IssueSituationVO> issueSituationVOS = issueSituationWrapper.entityToVO(issueSituations);
        List<PageData> pageDataList = new ArrayList<>();
        try {
            if (CollectionUtil.isNotEmpty(issueSituationVOS)) {
                for (IssueSituationVO vo : issueSituationVOS) {
                    PageData pd = new PageData();
                    pd.put("id", vo.getId());
                    pd.put("UNITNAME", vo.getFillCompanyName());
                    pd.put("APPLICANTNAME", vo.getCreateUserName());
                    pd.put("applicantId", vo.getCreateUser());
                    pd.put("applyOrganizationId", vo.getFillCompanyName());
                    pd.put("formType", FormTypeConstant.MS_ISSUE_SITUATION);
                    pd.put("orgName", vo.getFillCompanyName());
                    pageDataList.add(pd);
                }
            }
            return pageDataList;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return pageDataList;
    }

    @Override
    public List<Integer> getFormType() {
        return Collections.singletonList(FormTypeConstant.MS_ISSUE_SITUATION);
    }

    @Override
    public void goBackToStash(String formId) {
        handleStatus(Long.valueOf(formId), UNREVIEWED);
    }

    @Override
    public List<PageData> orgsForNum(PageData pd) {
        ArrayList<String> orgIds = (ArrayList<String>) pd.get("orgIds");
        ArrayList<PageData> pdlist = new ArrayList<>();
        String endTime = pd.getString("endTime");
        for (String orgid : orgIds) {
            PageData pageData1 = new PageData();
            pageData1.put("companyId", orgid);
            pageData1.put("endTime", endTime + "-31");
            PageData outData = new PageData();
            List<PageData> list = issueSituationMapper.issuelist2(pageData1);
            List<PageData> pd1 = new ArrayList<PageData>();
            HashMap<String,PageData> issueTypeMap=new HashMap<>();
            for (PageData pageData : list) {
                if (pageData.getString("companyId") != null) {
                    if(StringUtil.isNotBlank(pageData.getString("issueType"))){
                        String issueType = pageData.getString("issueType");
                        if(issueTypeMap==null||issueTypeMap.get(issueType)==null){
                            PageData dataNew = new PageData();
                            dataNew = IssueSituationServiceImpl.initPd(dataNew);
                            dataNew.put("issueType",issueType);
                            issueTypeMap.put(issueType,dataNew);
                        }
                        PageData org = orgzationService.getCompanyNameById(pageData.getString("companyId"));
                        if (org != null) {
                            pageData.put("orgName", org.getString("name"));
                            outData.put("orgName", org.getString("name"));
                        }
                        String fillDate = pageData.getString("fillDate");
                        fillDate = IssueSituationServiceImpl.covnDate(fillDate);
                        pageData.put("fillDate", fillDate);
                        PageData issueTypePageData=issueTypeMap.get(issueType);
                        issueTypePageData=IssueSituationServiceImpl.lastyearSum(pageData, issueTypePageData, endTime);
                    }
                }
            }
            if(issueTypeMap!=null){
                for (Map.Entry<String, PageData> entry : issueTypeMap.entrySet()) {
                    pd1.add(entry.getValue());
                    System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
                }
            }
            outData.put("list", pd1);
            if (outData.getString("orgName") != null) {
                pdlist.add(outData);
            }
        }
        return pdlist;
    }

}
